<template>
	<view class="wrap">
		<view v-if="items.length===0" class="empty">购物车是空的～</view>
		<view v-else>
			<view class="shop-hd">
				<label class="ck">
					<checkbox :checked="allChecked" @click.stop="toggleAll" />
					<text class="ck-text">全选</text>
				</label>
				<text class="shop-name">海D捞旗舰店</text>
			</view>
			<view v-for="it in items" :key="it.productId" class="row">
				<label class="ck">
					<checkbox :checked="checkedMap[it.productId]===true" @click.stop="toggle(it)" />
				</label>
				<image class="pic" :src="productCover(it.productId)" mode="aspectFill" @click="goDetail(it.productId)" />
				<view class="meta" @click="goDetail(it.productId)">
					<text class="title">{{ productTitle(it.productId) }}</text>
					<view class="price">¥{{ productPrice(it.productId) }}</view>
					<view class="qty">
						<button class="qt" @click.stop="dec(it)">-</button>
						<text class="num">{{ it.quantity }}</text>
						<button class="qt" @click.stop="inc(it)">+</button>
					</view>
				</view>
				<button class="del" @click.stop="checkoutOne(it)">结算</button>
			</view>
		</view>

		<view v-if="items.length>0" class="bar">
			<label class="ck">
				<checkbox :checked="allChecked" @click.stop="toggleAll" />
				<text class="ck-text">全选</text>
			</label>
			<view class="sum">合计：<text class="sum-num">¥{{ selectedAmount.toFixed(2) }}</text></view>
			<view class="ops">
				<button class="op danger" @click="removeSelected" :disabled="selectedIds.length===0">移除</button>
				<button class="op primary" @click="checkoutSelected" :disabled="selectedIds.length===0">结算</button>
			</view>
		</view>
	</view>
</template>

<script>
import { api, request } from '../../utils/request.js'
import { BASE_URL } from '../../utils/server.js'

export default {
	data(){ return { items:[], totalAmount:0, productsCache:{}, checkedMap:{} } },
	onShow(){ this.load(); },
	computed:{
		selectedIds(){ return this.items.filter(it=>this.checkedMap[it.productId]===true).map(it=>it.productId); },
		selectedCount(){ return this.selectedIds.length; },
		selectedAmount(){ let s=0; for(const it of this.items){ if(this.checkedMap[it.productId]){ const p=this.productsCache[it.productId]; if(p) s += Number(p.price||0)*it.quantity; } } return s; },
		allChecked(){ return this.items.length>0 && this.items.every(it=>this.checkedMap[it.productId]===true); }
	},
	methods:{
		async load(){
			try{
				const res = await api.cartList();
				if(res.code===0){
					this.items = res.data.items || [];
					this.totalAmount = res.data.totalAmount || 0;
					for(const it of this.items){ this.fetchProduct(it.productId); if(this.checkedMap[it.productId]===undefined){ this.$set(this.checkedMap, it.productId, false); } }
				}else{ uni.showToast({icon:'none', title:res.message}); }
			}catch(e){ uni.showToast({icon:'none', title:'加载失败'}); }
		},
		async fetchProduct(id){ if(this.productsCache[id]) return; try{ const p = await api.getProduct(id); if(p.code===0){ this.$set(this.productsCache, id, p.data); } }catch{} },
		productTitle(id){ return this.productsCache[id]?.title || `商品#${id}`; },
		productCover(id){ return this.getImageUrl(this.productsCache[id]?.coverImage); },
		productPrice(id){ return this.productsCache[id]?.price || 0; },
		getImageUrl(url) {
			if (!url) return '/static/logo.png';
			if (url.startsWith('http')) return url;
			return BASE_URL + url;
		},
		async inc(it){ await this.updateQty(it, it.quantity+1); },
		async dec(it){ if(it.quantity>1) await this.updateQty(it, it.quantity-1); },
		async updateQty(it, q){ try{ const res = await api.cartUpdate({ productId:it.productId, quantity:q }); if(res.code===0){ it.quantity = q; this.recalc(); } }catch{ uni.showToast({icon:'none', title:'更新失败'}); } },
		recalc(){ let total=0; for(const it of this.items){ const p=this.productsCache[it.productId]; if(p) total += Number(p.price||0)*it.quantity; } this.totalAmount = total; },
		toggle(it){ this.$set(this.checkedMap, it.productId, !this.checkedMap[it.productId]); },
		toggleAll(){ const v=!this.allChecked; for(const it of this.items){ this.$set(this.checkedMap, it.productId, v); } },
		async remove(it){ try{ const res = await api.cartRemove(it.productId); if(res.code===0){ this.items = this.items.filter(x=>x.productId!==it.productId); this.recalc(); this.$delete(this.checkedMap, it.productId); } } catch{ uni.showToast({icon:'none', title:'删除失败'}); } },
		async removeSelected(){ const ids=this.selectedIds; if(ids.length===0){ uni.showToast({icon:'none', title:'未选择'}); return; } for(const pid of ids){ try{ await api.cartRemove(pid); }catch{} } this.load(); },
		async checkout(){ uni.showToast({icon:'none', title:'请使用结算按钮'}); },
		checkoutSelected(){ const ids=this.selectedIds; if(ids.length===0){ uni.showToast({icon:'none', title:'未选择'}); return; } const query = encodeURIComponent(JSON.stringify(ids)); uni.navigateTo({ url:`/pages/order/confirm?type=cart&selected=${query}` }); },
		checkoutOne(it){ const query = encodeURIComponent(JSON.stringify([it.productId])); uni.navigateTo({ url:`/pages/order/confirm?type=cart&selected=${query}` }); }
		,goDetail(pid){ uni.navigateTo({ url: `/pages/product/detail?id=${pid}` }); }
	}
}
</script>

<style>
.wrap{ padding-bottom: 300rpx; }
.empty{ text-align:center; color:#888; padding: 40rpx 0; }
.shop-hd{ display:flex; align-items:center; justify-content: space-between; padding: 12rpx 16rpx; color:#333; }
.shop-name{ font-weight: 600; }
.row{ display:flex; align-items:center; background:#fff; padding: 16rpx; border-radius: 12rpx; margin: 12rpx 16rpx; gap: 12rpx; box-shadow: 0 6rpx 20rpx rgba(0,0,0,.05); }
.ck{ display:flex; align-items:center; gap: 8rpx; }
.ck-text{ color:#666; }
.pic{ width: 140rpx; height: 140rpx; border-radius: 12rpx; background:#fafafa; }
.meta{ flex:1; }
.title{ display:block; color:#333; font-size: 28rpx; }
.price{ color:#ff4d4f; font-weight: 600; margin-top: 8rpx; }
.qty{ display:flex; align-items:center; gap: 12rpx; margin-top: 8rpx; }
.num{ width: 60rpx; text-align:center; }
.del{ background:#f56c6c; color:#fff; }
.bar{ position: fixed; left:0; right:0; bottom: calc(100rpx + env(safe-area-inset-bottom)); padding: 14rpx 16rpx 14rpx; background:#fff; display:flex; align-items:center; gap: 12rpx; box-shadow: 0 -6rpx 20rpx rgba(0,0,0,.05); }
/* #ifdef MP-WEIXIN */
.bar{ bottom: 0; padding-bottom: calc(14rpx + env(safe-area-inset-bottom)); }
/* #endif */
.sum{ flex:1; text-align:right; color:#333; }
.sum-num{ color:#ff4d4f; font-weight: 700; }
.ops{ display:flex; gap: 12rpx; }
.op{ padding: 14rpx 22rpx; border-radius: 999rpx; border: 2rpx solid #ddd; background:#fff; font-size: 26rpx; }
.op.primary{ border-color:#ff7a45; color:#ff7a45; }
.op.danger{ border-color:#f56c6c; color:#f56c6c; }
</style>

